﻿using System;
using System.Collections.Generic;
using WinRTFramework.FrameworkConfiguration;

namespace WinRTFramework.DefaultImplementations
{
    public class DefaultViewViewModelMapper : IViewViewModelMapper
    {
        Dictionary<Type, Type> _viewTypeToViewModelTypeMap = new Dictionary<Type, Type>();
        Dictionary<Type, Type> _viewModelTypeToViewTypeMap = new Dictionary<Type, Type>();

        private readonly IIoCAdapter _iocAdapter;

        public DefaultViewViewModelMapper(Dictionary<Type, Type> viewTypeToViewModelTypeMap, IIoCAdapter iocAdapter)
        {
            _viewTypeToViewModelTypeMap = viewTypeToViewModelTypeMap;
            _iocAdapter = iocAdapter;

            CreateViewModelTypeToViewTypeMap();
        }

        private void CreateViewModelTypeToViewTypeMap()
        {
            _viewModelTypeToViewTypeMap = new Dictionary<Type, Type>();

            foreach (Type viewType in _viewTypeToViewModelTypeMap.Keys)
            {
                Type viewModelType = _viewTypeToViewModelTypeMap[viewType];

                if(_viewModelTypeToViewTypeMap.ContainsKey(viewModelType))
                    throw new InvalidOperationException("The DefaultViewViewModelMapper requires a unique 1-1 mapping between view and viewmodel types. However, multiple views map to the view model type " + viewModelType + ".");

                _viewModelTypeToViewTypeMap.Add(viewModelType, viewType);
            }
        }


        public virtual Type GetViewTypeForViewModelType(Type viewModelType, object navigationParameter)
        {
            if (!_viewModelTypeToViewTypeMap.ContainsKey(viewModelType))
                throw new ArgumentOutOfRangeException("ViewModelType " + viewModelType + " is unknown. Please make sure to pass it in the constructor's View<->ViewModel map.");

            Type viewType = _viewModelTypeToViewTypeMap[viewModelType];
            return viewType;
        }

        public virtual object GetViewModelForView(Type viewType, object navigationParameter)
        {
            if(!_viewTypeToViewModelTypeMap.ContainsKey(viewType))
                throw new ArgumentOutOfRangeException("ViewType " + viewType + " is unknown. Please make sure to pass it in the constructor's View<->ViewModel map.");

            Type viewModelType = _viewTypeToViewModelTypeMap[viewType];
            return _iocAdapter.GetInstanceOfType(viewModelType);
        }
    }
}
